package com.iot08.api.filter;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iot08.api.utils.SpringContextUtil;
import com.iot08.common.constant.CacheEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
 * 适配 HTTP 请求的 表单提交方式 和 json body提交方式都能获取到参数的问题的类
 * @author weichao 1299101858@qq.com
 * @version 1.0
 * @date 2/26/22 10:40 AM
 */
@Slf4j
public class ModifyParametersWrapper extends HttpServletRequestWrapper {

    private Map<String, String[]> parameterMap = new HashMap<>(); // 所有参数的Map集合

    public ModifyParametersWrapper(HttpServletRequest request) {

        super(request);
        String contentType = request.getContentType();

        if (request.getParameterMap() != null && request.getParameterMap().size() > 0) {

            //if ("application/x-www-form-urlencoded".equalsIgnoreCase(contentType)) {
            // 获取参数
            for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
                //由于赛诺的接口参数有此问题,所以需要对参数进行重新赋值一下 switch 是关键词
               /* if("switch".equals(entry.getKey())){
                    parameterMap.put("switchStatus", entry.getValue());
                }*/
                parameterMap.put(entry.getKey(), entry.getValue());
            }
        }

        // json格式 json格式需要从request的输入流中解析获取
        /*if ("application/json".equalsIgnoreCase(contentType)) {
            try{
                // 使用 commons-io中 IOUtils 类快速获取输入流内容
                String paramJson = IOUtils.toString(request.getInputStream(), "UTF-8");
                JSONObject parseObject = JSONObject.parseObject(paramJson);
                for (String key : parseObject.keySet()) {
                    //由于赛诺的接口参数有此问题,所以需要对参数进行重新赋值一下 switch 是关键词
                    if("switch".equals(key)){
                        parameterMap.put("switchStatus", new String[] {parseObject.getString(key)});
                    }
                    parameterMap.put(key, new String[] {parseObject.getString(key)});
                }

            }catch (Exception error){

            }
        }*/
        if(request.getMethod().equals("PATCH") ||
                request.getMethod().equals("DELETE")){
            try{
                // 使用 commons-io中 IOUtils 类快速获取输入流内容
                String paramJson = IOUtils.toString(request.getInputStream(), "UTF-8");
                // URL 解码一下
                //URL解码
                try{
                    paramJson = URLDecoder.decode(paramJson, "utf-8");
                }catch (Exception error){
                    log.error("读取参数 URL解码时错误Error:"+error.getMessage(), error);
                }
                String[] paramArr = paramJson.split("&");
                for (String item : paramArr) {
                    String[] itemArr = item.split("=");
                    String key = itemArr[0];
                    String value = "";
                    if (itemArr.length > 1) {
                        value = itemArr[1];
                    }
                    //由于赛诺的接口参数有此问题,所以需要对参数进行重新赋值一下 switch 是关键词
                   /* if("switch".equals(key)){
                        parameterMap.put("switchStatus", new String[] {value});
                    }*/
                    parameterMap.put(key, new String[] {value});
                }

            }catch (Exception error){
                log.error("读取参数时错误:error:"+error.getMessage(), error);
            }
        }
        String activeProfile = SpringContextUtil.getActiveProfile();
        if("dev".contains(activeProfile)||"local".contains(activeProfile)){
            //测试环境
            //获取请求头信息
            Enumeration headerNames = request.getHeaderNames();
            //使用循环遍历请求头，并通过getHeader()方法获取一个指定名称的头字段
            StringBuilder sb = new StringBuilder();
            sb.append("请求头:\n");
            while (headerNames.hasMoreElements()){
                String headerName = (String) headerNames.nextElement();
                sb.append(headerName + " : " + request.getHeader(headerName) +"\n");
            }
            sb.append("请求URL:"+request.getRequestURL()+"\n");
            sb.append("请求方式:"+request.getMethod()+"\n");
            sb.append("参数方式:"+contentType+" 请求参数:\n");
            for (String key : parameterMap.keySet()) {
                String[] strings = parameterMap.get(key);

//            StringBuilder tempValueSb = new StringBuilder();
//            for (int i = 0; i < strings.length; i++) {
//                tempValueSb.append(strings[i]+" ");
//            }
//            sb.append(key+" : "+tempValueSb+"\n");
                if(strings.length > 0){
                    //微聊上传的图片和语音不打印
                    if("content".equals(key) && strings[0].length() > 500){
                        sb.append(key+" : <数据过长,不显示>"+"\n");
                    }else{
                        sb.append(key+" : "+strings[0]+"\n");
                    }

                }
            }
            //打印http请求的信息
            log.info(sb.toString());
        }
    }

    public static void main(String[] args){
        String [] strings = new String[] {"aaa", "bbb"};
        StringBuilder tempValueSb = new StringBuilder();
        for (int i = 0; i < strings.length; i++) {
                tempValueSb.append(strings[i]);
            }
        System.out.println(String.format("strings: %s", tempValueSb));
    }

    /**

     * 获取所有参数名

     * @return 返回所有参数名

     */

    @Override

    public Enumeration getParameterNames() {

        Vector vector = new Vector(parameterMap.keySet());

        return vector.elements();

    }

    /**

     * 获取指定参数名的值，如果有重复的参数名，则返回第一个的值 接收一般变量 ，如text类型

     * @param name

     * 指定参数名

     * @return 指定参数名的值

     */

    @Override

    public String getParameter(String name) {

        String[] results = parameterMap.get(name);

        if (results == null || results.length <= 0)

            return null;

        else {

            return results[0];

        }

    }

    /**

     * 获取指定参数名的所有值的数组，如：checkbox的所有数据

     * 接收数组变量 ，如checkobx类型

     */

    @Override

    public String[] getParameterValues(String name) {

        String[] results = parameterMap.get(name);

        if (results == null || results.length <= 0)

            return null;

        else {
            //如果需要 解密参数的,可以在此完成解密
//            int length = results.length;
//            if (needDecrpty()) {
//
//                for (int i = 0; i < length; i++) {
//
//                    results[i] = decrpty(results[i]);
//
//                }
//
//            }

            return results;

        }

    }

}
